package com.jackie.easyble.ui.activities.scanrecordparse

import android.bluetooth.le.ScanResult
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.os.ParcelUuid
import android.view.View
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.library.adapter4.BaseQuickAdapter
import com.sscl.easyble.AdvertiseStruct
import com.sscl.easyble.BleUtils
import com.sscl.easyble.ServiceDataInfo
import com.sscl.easyble.extensions.toByteArray
import com.jackie.easyble.IntentConstants
import com.jackie.easyble.R
import com.jackie.easyble.ui.adapter.ScanRecordParseAdStructRecyclerViewAdapter
import com.jackie.easyble.ui.adapter.ScanRecordServiceDataRecyclerViewAdapter
import com.jackie.easyble.ui.adapter.ScanRecordUuidRecyclerViewAdapter
import com.jackie.easyble.databinding.ActivityScanRecordParseBinding
import com.sscl.baselibrary.activity.BaseDataBindingAppCompatActivity
import com.sscl.baselibrary.utils.DebugUtil
import com.sscl.baselibrary.utils.DefaultItemDecoration
import com.sscl.baselibrary.utils.ToastUtil
import com.sscl.baselibrary.utils.Tool
import com.sscl.baselibrary.utils.toHexStringWithSpace

/**
 * 广播数据解析界面
 */
class ScanRecordParseActivity : BaseDataBindingAppCompatActivity<ActivityScanRecordParseBinding>() {

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 属性声明
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    /* * * * * * * * * * * * * * * * * * * 可空属性 * * * * * * * * * * * * * * * * * * */

    /**
     * 某个设备
     */
    private var scanResult: ScanResult? = null

    /* * * * * * * * * * * * * * * * * * * 常量属性 * * * * * * * * * * * * * * * * * * */

    /**
     * viewModel
     */
    private val scanRecordParseActivityViewModel by viewModels<ScanRecordParseActivityViewModel> {
        ScanRecordParseActivityViewModel.ScanRecordParseActivityViewModelFactory
    }

    /**
     * 点击事件
     */
    private val onClickListener = View.OnClickListener {
        when (it.id) {
            binding.copyScanRecordBtn.id -> {
                Tool.setDataToClipboard(
                    this@ScanRecordParseActivity,
                    TAG,
                    scanResult?.scanRecord?.bytes.toHexStringWithSpace() ?: ""
                )
                ToastUtil.toastLong(this, R.string.scan_record_copied)
            }
        }
    }

    /**
     * 广播包AD结构列表适配器
     */
    private val scanRecordParseAdStructRecyclerViewAdapter =
        ScanRecordParseAdStructRecyclerViewAdapter()

    /**
     * 广播包服务信息列表适配器
     */
    private val scanRecordServiceDataRecyclerViewAdapter =
        ScanRecordServiceDataRecyclerViewAdapter()

    /**
     * 广播包UUID信息列表适配器
     */
    private val scanRecordUuidRecyclerViewAdapter = ScanRecordUuidRecyclerViewAdapter()

    /**
     * AD结构列表点击事件
     */
    private val onAdvertiseStructItemClickListener =
        BaseQuickAdapter.OnItemClickListener<AdvertiseStruct> { adapter, view, position ->
            showAdStructItemOptionsDialog(scanRecordParseAdStructRecyclerViewAdapter.items[position])
        }

    /**
     *  服务信息列表点击事件
     */
    private val onServiceDataInfoItemClickListener =
        BaseQuickAdapter.OnItemClickListener<ServiceDataInfo> { adapter, view, position ->
            showServiceDataOptionsDialog(scanRecordServiceDataRecyclerViewAdapter.items[position])
        }

    /**
     *  UUID信息列表点击事件
     */
    private val onUuidItemClickListener =
        BaseQuickAdapter.OnItemClickListener<ParcelUuid> { adapter, view, position ->
            showUuidOptionsDialog(scanRecordServiceDataRecyclerViewAdapter.items[position])
        }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 实现方法
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    /**
     * 设置布局
     */
    override fun setLayout(): Int {
        return R.layout.activity_scan_record_parse
    }

    /**
     * 标题栏的返回按钮被按下的时候回调此方法
     */
    override fun titleBackClicked(): Boolean {
        return false
    }

    /**
     * 在设置布局之前需要进行的操作
     */
    override fun doBeforeSetLayout() {
        getIntentData()
    }

    /**
     * 设置DataBinding
     * 可在此处设置binding的viewModel或观察者等操作
     */
    override fun setBinding() {
        binding.viewModel = scanRecordParseActivityViewModel
    }

    /**
     * 在设置布局之后，进行其他操作之前，所需要初始化的数据
     */
    override fun doBeforeInitOthers() {
        setTitleText(R.string.view_scan_record)
    }

    /**
     * 初始化控件数据
     */
    override fun initViewData(savedInstanceState: Bundle?) {
        initAdStructRvData()
        initServiceDataRvData()
        initUUidRvData()
    }

    /**
     * 初始化其他数据
     */
    override fun initOtherData() {

    }

    /**
     * 初始化事件
     */
    override fun initEvents() {
        binding.copyScanRecordBtn.setOnClickListener(onClickListener)
        scanRecordParseAdStructRecyclerViewAdapter.setOnItemClickListener(
            onAdvertiseStructItemClickListener
        )
        scanRecordServiceDataRecyclerViewAdapter.setOnItemClickListener(
            onServiceDataInfoItemClickListener
        )
        scanRecordUuidRecyclerViewAdapter.setOnItemClickListener(
            onUuidItemClickListener
        )
    }

    /**
     * 在最后进行的操作
     */
    override fun doAfterAll() {
        if (scanResult == null) {
            finish()
            return
        }
        setData()
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 私有方法
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    /**
     * 获取Intent传递的数据
     */
    private fun getIntentData() {
        scanResult = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            intent.getParcelableExtra(IntentConstants.SCAN_RESULT, ScanResult::class.java)
        } else {
            @Suppress("DEPRECATION")
            intent.getParcelableExtra(IntentConstants.SCAN_RESULT)
        }
    }

    /**
     * 初始化AD结构展示列表数据
     */
    private fun initAdStructRvData() {
        binding.adStructListRv.layoutManager = LinearLayoutManager(this)
        binding.adStructListRv.addItemDecoration(DefaultItemDecoration.newLine(Color.GRAY))
        binding.adStructListRv.adapter = scanRecordParseAdStructRecyclerViewAdapter
    }

    /**
     * 初始化服务信息展示列表数据
     */
    private fun initServiceDataRvData() {
        binding.serviceInfoListRv.layoutManager = LinearLayoutManager(this)
        binding.serviceInfoListRv.addItemDecoration(DefaultItemDecoration.newLine(Color.GRAY))
        binding.serviceInfoListRv.adapter = scanRecordServiceDataRecyclerViewAdapter
    }

    /**
     *  初始化UUID展示列表数据
     */
    private fun initUUidRvData() {
        binding.uuidInfoListRv.layoutManager = LinearLayoutManager(this)
        binding.uuidInfoListRv.addItemDecoration(DefaultItemDecoration.newLine(Color.GRAY))
        binding.uuidInfoListRv.adapter = scanRecordUuidRecyclerViewAdapter
    }

    /**
     * 显示AD结构的选项被点击的操作选项
     */
    private fun showAdStructItemOptionsDialog(advertiseStruct: AdvertiseStruct) {
        AlertDialog.Builder(this)
            .setTitle(R.string.ad_struct_options_dialog_title)
            .setItems(R.array.ad_struct_options) { _, which ->
                when (which) {
                    //复制整个AD结构数据
                    0 -> {
                        val byteArray = advertiseStruct.toByteArray()
                        Tool.setDataToClipboard(
                            this@ScanRecordParseActivity,
                            TAG,
                            byteArray.toHexStringWithSpace() ?: ""
                        )
                        ToastUtil.toastLong(this, R.string.ad_struct_copied)
                    }
                    //仅复制AD数据
                    1 -> {
                        val data = advertiseStruct.data
                        Tool.setDataToClipboard(
                            this@ScanRecordParseActivity,
                            TAG,
                            data.toHexStringWithSpace() ?: ""
                        )
                        ToastUtil.toastLong(this, R.string.ad_data_copied)
                    }
                }
            }
            .setNegativeButton(R.string.cancel, null)
            .show()
    }

    /**
     * 显示服务信息的选项被点击的操作选项
     */
    private fun showServiceDataOptionsDialog(serviceDataInfo: ServiceDataInfo) {
        AlertDialog.Builder(this)
            .setTitle(R.string.service_data_options_dialog_title)
            .setItems(R.array.service_data_options) { _, which ->
                when (which) {
                    //复制服务UUID
                    0 -> {
                        val uuidString = serviceDataInfo.parcelUuid.toString()
                        Tool.setDataToClipboard(
                            this@ScanRecordParseActivity,
                            TAG,
                            uuidString
                        )
                        ToastUtil.toastLong(this, R.string.service_uuid_copied)
                    }
                    //仅复制AD数据
                    1 -> {
                        val data = serviceDataInfo.value
                        DebugUtil.warnOut(TAG, data.toHexStringWithSpace() ?: "")
                        Tool.setDataToClipboard(
                            this@ScanRecordParseActivity,
                            TAG,
                            data.toHexStringWithSpace() ?: ""
                        )
                        ToastUtil.toastLong(this, R.string.service_data_copied)
                    }
                }
            }
            .setNegativeButton(R.string.cancel, null)
            .show()
    }

    /**
     * 直接复制整个UUID
     */
    private fun showUuidOptionsDialog(serviceDataInfo: ServiceDataInfo) {
        val uuidString = serviceDataInfo.parcelUuid.toString()
        Tool.setDataToClipboard(
            this@ScanRecordParseActivity,
            TAG,
            uuidString
        )
        ToastUtil.toastLong(this, R.string.service_uuid_copied)
    }

    /**
     * 设置数据展示
     */
    private fun setData() {
        val scanResult = scanResult ?: return
        scanRecordParseActivityViewModel.scanResult.value = scanResult

        val scanRecord = scanResult.scanRecord ?: return
        scanRecordParseAdStructRecyclerViewAdapter.addAll(
            BleUtils.getAdvertiseRecords(
                scanRecord
            )
        )
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val serviceSolicitationUuids =
                scanRecord.serviceSolicitationUuids
            if (serviceSolicitationUuids.isEmpty()) {
                DebugUtil.warnOut(TAG, "serviceSolicitationUuids 为空")
            } else {
                for (serviceSolicitationUuid in serviceSolicitationUuids) {
                    DebugUtil.warnOut(
                        TAG,
                        "serviceSolicitationUuid = ${serviceSolicitationUuid.uuid}"
                    )
                }
            }
        }
        scanRecordServiceDataRecyclerViewAdapter.addAll(
            BleUtils.getServiceDataInfoList(
                scanRecord
            )
        )
        val advertiseFlags = scanRecord.advertiseFlags
        DebugUtil.warnOut(TAG, "advertiseFlags = $advertiseFlags")
        val serviceUuids = scanRecord.serviceUuids
        if (serviceUuids == null || serviceUuids.isEmpty()) {
            DebugUtil.warnOut(TAG, "serviceUuids 为空")
        } else {
            for (serviceUuid in serviceUuids) {
                DebugUtil.warnOut(TAG, "serviceUuid ${serviceUuid.uuid}")
            }
        }
        scanRecordUuidRecyclerViewAdapter.addAll(serviceUuids)
        val txPowerLevel = scanRecord.txPowerLevel
        DebugUtil.warnOut(TAG, "txPowerLevel $txPowerLevel")
    }
}